package com.joinway.framework.extension.image.coder;

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.joinway.framework.extension.image.coder.type.ImageSize;

public class QRImageCoder implements IImageCoder {

	private static final String SUFFIX = "png";
	
	/**
	 * 二维码编码成png格式
	 * 
	 * @param contents 二维码内容
	 * @param image 输出图片文件
	 * @param width 宽度像素
 	 * @param height 高度像素
	 */
	@Override
	public void encode(String contents, String image, int width, int height) throws Exception {
		Map<EncodeHintType, Object> hints = new HashMap<>();
		// 指定纠错等级
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
		// 指定编码格式
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
		
		BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);

		MatrixToImageWriter.writeToPath(bitMatrix, SUFFIX, new File(image).toPath());
	}

	/**
	 * 二维码编码成png格式
	 * 
	 * @param contents 二维码内容
	 * @param image 输出图片文件
	 * @param size 图片大小
	 */
	@Override
	public void encode(String contents, String image, ImageSize size) throws Exception {
		encode(contents, image, size.width, size.height);
	}

	@Override
	public void encode(String contents, String image) throws Exception {
		encode(contents, image, ImageSize.QRLarge.width, ImageSize.QRLarge.height);
	}

	/**
	 * 二维码解码
	 * 
	 * @param image 二维码文件路径
	 * @return String
	 */
	@Override
	public String decode(String image) throws Exception {
		BufferedImage bufferedImage = ImageIO.read(new File(image));
		
		LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

		Map<DecodeHintType, Object> hints = new HashMap<>();
		hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");

		Result result = new MultiFormatReader().decode(bitmap, hints);
		return result.getText();
	}

}
